package com.ndood;


import java.util.concurrent.DelayQueue;

import javax.annotation.PostConstruct;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.ndood.polling.app.task.PollingDelayTask;

import lombok.extern.slf4j.Slf4j;


/**
 * polling启动类
 * https://gitee.com/roncoocom/roncoo-pay/blob/master/roncoo-pay-app-order-polling/src/main/java/com/roncoo/pay/AppOrderPollingApplication.java
 */
@EnableCaching
@EnableTransactionManagement
@Slf4j
@SpringBootApplication
@MapperScan({"com.ndood.*.base.dao"})
public class PollingApplication {
	
	public static DelayQueue<PollingDelayTask> tasks = new DelayQueue<PollingDelayTask>();
	
	@Autowired
    private ThreadPoolTaskExecutor threadPool;
	
	private static ThreadPoolTaskExecutor cacheThreadPool;
	
	public static void main(String[] args) {
		SpringApplication.run(PollingApplication.class, args);
	}
	
	@PostConstruct
    public void init() {
        cacheThreadPool = threadPool;
        startThread();
    }
	
	private void startThread() {
        log.info("==>startThread");

        cacheThreadPool.execute(new Runnable() {
            public void run() {
                try {
                    while (true) {
                        Thread.sleep(100);
                        log.info("==>threadPool.getActiveCount():" + cacheThreadPool.getActiveCount());
                        log.info("==>threadPool.getMaxPoolSize():" + cacheThreadPool.getMaxPoolSize());
                        // 如果当前活动线程等于最大线程，那么不执行
                        if (cacheThreadPool.getActiveCount() < cacheThreadPool.getMaxPoolSize()) {
                            log.info("==>tasks.size():" + tasks.size());
                            final PollingDelayTask task = tasks.take(); //使用take方法获取过期任务,如果获取不到,就一直等待,知道获取到数据
                            if (task != null) {
                                cacheThreadPool.execute(new Runnable() {
                                    public void run() {
                                        tasks.remove(task);
                                        task.run(); // 执行通知处理
                                        log.info("==>tasks.size():" + tasks.size());
                                    }
                                });
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("系统异常;", e);
                }
            }
        });
    }
}